#include "widget.h"
#include "ui_widget.h"
#include "mytable.h"
#include <QFileDialog>
#include <QMessageBox>
#include "xlsxdocument.h"
#include "xlsxcellformula.h"
#include "xlsxcell.h"

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{
    ui->setupUi(this);
    init();
    initStackedWidget();
    initConnect();
}

Widget::~Widget()
{
    delete ui;
    delete info;
    delete error;
}

void Widget::init()
{
    QDate currentDate = QDate::currentDate();
    ui->end_year->setText(QString::number(currentDate.year()));

    // 如果是上半年,为第一学期，开始时间
    if (currentDate.month() < 7) {
        ui->comboBox->setCurrentIndex(0);
    } else {
        ui->comboBox->setCurrentIndex(1);
    }

    // 阻塞选择需要的课程
    cs = new CourseSelection();
    cs->setWindowModality(Qt::ApplicationModal); // 使子界面只打开一次 开始
    cs->setAttribute(Qt::WA_ShowModal, true);    // 使子界面只打开一次 结束
}

void Widget::initStackedWidget()
{
    info = new Info(this);
    error = new Error(this);
    ui->stackedWidget->addWidget(info);
    ui->stackedWidget->addWidget(error);
    ui->stackedWidget->setCurrentIndex(0);
}

void Widget::initConnect()
{
    // 给 info 窗口添加信息
    connect(this, &Widget::appendInfoMessage, info, &Info::dealInfoMessage, Qt::QueuedConnection);
    // 清空 info 窗口的信息
    connect(this, &Widget::clearInfoMessage, info, &Info::dealClearInfoMessage, Qt::QueuedConnection);

    // 给 error 窗口添加信息
    connect(this, &Widget::appendErrorMessage, error, &Error::dealErrorMessage, Qt::QueuedConnection);
    // 清空 error 窗口信息
    connect(this, &Widget::clearErrorMessage, error, &Error::dealClearErrorMessage, Qt::QueuedConnection);

    // 选择课程后的返回值
    connect(cs, &CourseSelection::selectedCourseList, this, &Widget::dealSelectedCourseList);
}

bool Widget::loadCourse()
{
    // 检查文件是否存在
    if (!QFile::exists(courseScorePath)) {
        emit appendErrorMessage("文件："+courseScorePath+" 不存在\n");
        return false;
    }

    // 读取Excel文件
    QXlsx::Document xlsx(courseScorePath);
    if (!xlsx.load()) {
        emit appendErrorMessage("文件："+courseScorePath+" 加载失败\n");
        return false;
    }

    // 添加课程
    emit appendInfoMessage("开始录入课程......\n");
    for (int col = config.COL_FIRST_COURSE_INFO_ON_GRADE;; col++) {
        Course c;
        if (!c.loadCourse(col , xlsx.read(config.ROW_FIRST_COURSE_INFO_ON_GRADE, col).toString().trimmed())) break;
        this->courseList.append(c);
    }
    if (courseList.isEmpty()){
        emit appendErrorMessage("该表格中没有课程信息\n");
        return false;
    }

    // 自定义需要计算的课程
    cs->setCourseList(this->courseList);
    cs->show();
    if (cs->exec() != QDialog::Accepted) {
        return false;
    }
    showCourse();

    // 得到每个同学，每门课程的得分
    emit appendInfoMessage("开始录入课程分数......\n");
    int courseLen = this->courseList.length();

    for (int row = config.ROW_FIRST_STUDENT_ID_ON_GRADE;; row++) {
        QString xh = xlsx.read(row, config.COL_FIRST_STUDENT_ID_ON_GRADE).toString().trimmed();
        QString name = xlsx.read(row, config.COL_FIRST_STUDENT_NAME_ON_GRADE).toString().trimmed();
        if (xh.isEmpty()) {
            // 读取完成
            break;
        }
        Student s(xh, name);
        for (int col = 0; col < courseLen; col++) {
            int courseID = courseList[col].getId();
            QString score = xlsx.read(row, courseID).toString().trimmed();
            if (score.isEmpty()) {
                s.setCourseScore(courseID, -1);  // 没有成绩
            } else {
                s.setCourseScore(courseID, score.toDouble());
            }
        }
        students[xh] = s;
    }

    showStudent();
    return true;
}

bool Widget::loadCharity()
{
    // 检查文件是否存在
    if (!QFile::exists(charityScorePath)) {
        emit appendErrorMessage("文件："+charityScorePath+" 不存在\n");
        return false;
    }

    // 读取Excel文件
    QXlsx::Document xlsx(charityScorePath);
    if (!xlsx.load()) {
        emit appendErrorMessage("文件："+charityScorePath+" 加载失败\n");
        return false;
    }

    // 得到每个同学的公益分
    emit appendInfoMessage("开始录入公益分......\n");
    QMap<QString, int> studentsInSheet;
    QXlsx::CellRange range = xlsx.dimension();
    int rowCount = range.rowCount();
    for (int row = config.ROW_FIRST_STUDENT_ID_ON_CHARITY; row < rowCount; row++) {
        QString xh = xlsx.read(row, config.COL_FIRST_STUDENT_ID_ON_CHARITY).toString().trimmed();
        if (!xh.isEmpty()) {
            int score = readCellValue(xlsx, row, config.COL_CHARITY_SCORE_ON_CHARITY).toInt();
            studentsInSheet[xh] = score;
            if (!students.contains(xh)) {
                emit appendErrorMessage("公益分成绩加载错误：学生【"+xh+"】为公益分表中多出来的人，请检查该学生是否存在\n");
                emit appendInfoMessage("**********公益分成绩加载错误：学生【"+xh+"】为公益分表中多出来的人，请检查该学生是否存在\n");
            } else {
                students[xh].setCharityScore(score);
            }
        }
    }

    // 检查未录入的成绩
    for (Student s : students) {
        QString xh = s.getXh();
        if (!studentsInSheet.contains(xh)) {
            emit appendErrorMessage("公益分成绩加载错误：学生【"+xh+"】在学生列表中，但不在公益分表中，请检查该学生是否存在\n");
            emit appendInfoMessage("**********公益分成绩加载错误：学生【"+xh+"】在学生列表中，但不在公益分表中，请检查该学生是否存在\n");
        }
    }
    showCharity();
    return true;
}

bool Widget::loadConduct()
{
    // 检查文件是否存在
    if (!QFile::exists(conductScorePath)) {
        emit appendErrorMessage("文件："+conductScorePath+" 不存在\n");
        return false;
    }

    // 读取Excel文件
    QXlsx::Document xlsx(conductScorePath);
    if (!xlsx.load()) {
        emit appendErrorMessage("文件："+conductScorePath+" 加载失败\n");
        return false;
    }

    // 得到每个同学的操行分
    emit appendInfoMessage("开始录入操行分......\n");
    QMap<QString, int> studentsInSheet;
    QXlsx::CellRange range = xlsx.dimension();
    int rowCount = range.rowCount();
    for (int row = config.ROW_FIRST_STUDENT_ID_ON_CONDUCT;row < rowCount; row++) {
        QString xh = xlsx.read(row, config.COL_FIRST_STUDENT_ID_ON_CONDUCT).toString().trimmed();
        if (!xh.isEmpty()) {
            double score = readCellValue(xlsx, row, config.COL_CONDUCT_SCORE_ON_CONDUCT).toDouble();
            studentsInSheet[xh] = score;
            if (!students.contains(xh)) {
                emit appendErrorMessage("操行分成绩加载错误：学生【"+xh+"】为操行分表中多出来的人，请检查该学生是否存在\n");
                emit appendInfoMessage("**********操行分成绩加载错误：学生【"+xh+"】为操行分表中多出来的人，请检查该学生是否存在\n");
            } else {
                students[xh].setConductScore(score);
            }
        }
    }

    // 检查未录入的成绩
    for (Student s : students) {
        QString xh = s.getXh();
        if (!studentsInSheet.contains(xh)) {
            emit appendErrorMessage("操行分成绩加载错误：学生【"+xh+"】在学生列表中，但不在操行分表中，请检查该学生是否存在\n");
            emit appendInfoMessage("**********操行分成绩加载错误：学生【"+xh+"】在学生列表中，但不在操行分表中，请检查该学生是否存在\n");
        }
    }
    showConduct();
    return true;
}

QVariant Widget::readCellValue(QXlsx::Document& xlsx, const int row, const int col, const bool readVal)
{
    if(readVal) {
        QXlsx::Worksheet* ws = dynamic_cast<QXlsx::Worksheet*>(xlsx.sheet(xlsx.sheetNames().first()));
        std::shared_ptr<QXlsx::Cell> cell = ws->cellAt(row, col);
        if(cell != nullptr && cell->hasFormula()) {
            QVariant v = cell->value();
            QVariant emptyVariant;
            if(v.toString().compare(emptyVariant.toString()) == 0) {  // 如果值为空
                return "=" + cell->formula().formulaText();  // 返回公式
            } else {
                return cell->value();
            }
        }
    }

    return xlsx.read(row, col);
}

void Widget::showCourse()
{
    // 显示输出课程
    emit appendInfoMessage("已录入以下课程：\n");
    for (Course c : this->courseList){
        emit appendInfoMessage("--->"+c.toString() + "\n");
    }
}

void Widget::showCharity()
{
    // 显示输出公益分
    emit appendInfoMessage("已录入以下公益分：\n");
    for (Student s : this->students){
        emit appendInfoMessage("===>"+s.getXh()+" "+s.getName().leftJustified(3, '\t')+((s.getName().length() == 3)?"    " :""));
        emit appendInfoMessage("公益分："+QString::number(s.getCharityScore()) + "\n");
    }
}

void Widget::showConduct()
{
    // 显示输出操行分
    emit appendInfoMessage("已录入以下操行分：\n");
    for (Student s : this->students){
        emit appendInfoMessage("===>"+s.getXh()+" "+s.getName().leftJustified(3, '\t')+((s.getName().length() == 3)?"    " :""));
        emit appendInfoMessage(QString::number(s.getConductScore()) + "\n");
    }
}

void Widget::showStudent()
{
    // 显示输出课程
    emit appendInfoMessage("已经录入的所有学生信息：学生总人数（" +QString::number(this->students.size())+" 人）\n");
    for (Student s : this->students){
        emit appendInfoMessage("===>"+s.getXh()+" "+s.getName().leftJustified(3, '\t')+((s.getName().length() == 3)?"    " :""));
        for (Course c : this->courseList){
            emit appendInfoMessage("【"+c.getName()+":"+QString::number(s.getCourseScore(c.getId()))+"】");
        }
        emit appendInfoMessage("\n");
    }
}

void Widget::showAll()
{
    // 显示输出所有信息
    emit appendInfoMessage("计算完成后的所有学生信息：\n");
    for (Student s : this->students){
        emit appendInfoMessage("===>"+s.getXh()+" "+s.getName().leftJustified(3, '\t')+((s.getName().length() == 3)?"    " :""));
        for (Course c : this->courseList){
            emit appendInfoMessage("【"+c.getName()+":"+QString::number(s.getCourseScore(c.getId()))+"】");
        }

        emit appendInfoMessage("【课程成绩:"+QString::number(s.getKc())+"】【体育成绩:"+QString::number(s.getTy())+ "】\n");
    }
}

bool Widget::calculate(GradeLevel gradeLevel)
{
    emit appendInfoMessage("\n\n\n开始计算所有学生的成绩......\n");
    try {
        if (gradeLevel == GradeLevel::One || gradeLevel == GradeLevel::Two) {
            // 大一、大二
            for (Student& s : this->students) {
                double cj_sum = 0.0;  // 总成绩
                double xf_sum = 0.0;  // 总学分
                double gyf = s.getCharityScore();  // 公益分
                double cxf = s.getConductScore();  // 操行分
                double kc = 0;        // 课程成绩

                // 计算课程成绩、体育成绩
                emit appendInfoMessage("\n开始计算["+s.getName()+"]的成绩：");
                for (Course c : this->courseList) {
                    kc = s.getCourseScore(c.getId());
                    QRegularExpression re("^体育");
                    if (re.match(c.getName()).hasMatch()) {
                        // 体育成绩
                        s.setTy(kc * 0.1);

                    } else if (kc != -1) {
                        // 非体育成绩
                        cj_sum += kc * c.getXF();
                        xf_sum += c.getXF();
                        emit appendInfoMessage("【"+c.getName()+":"+QString::number(kc)+"/"+QString::number(c.getXF())+"/"+QString::number(cj_sum)+"/"+QString::number(xf_sum)+"】");
                    } else {
                        // 没有选修的课程
                        emit appendInfoMessage("【"+c.getName()+":未修/"+QString::number(c.getXF())+"/"+QString::number(cj_sum)+"/"+QString::number(xf_sum)+"】");
                    }
                }
                emit appendInfoMessage("【体育成绩单独计算:"+QString::number(kc)+"*0.1="+QString::number(kc*0.1)+"】");
                // 计算课程成绩
                s.setKc(cj_sum/xf_sum);

                // 计算公益分成绩
                s.setGyf(calculateCharityGrade(gyf));

                // 计算操行分成绩
                s.setCxf(cxf*0.11);

                // 计算奖学金成绩【课程成绩*0.7+体育*0.1+操行分*0.11+公益分成绩】
                s.setJxj(s.getKc()*0.7+s.getTy()+s.getCxf()+s.getGyf());

                emit appendInfoMessage("\n【课程成绩:"+QString::number(s.getKc())+"】"+
                                       "【体育成绩:"+QString::number(s.getTy())+ "】"+
                                       "【公益分成绩:"+QString::number(s.getGyf())+"】"+
                                       "【操行分成绩:"+QString::number(s.getCxf())+"】"+
                                       "【奖学金成绩:"+QString::number(s.getJxj())+"】\n");
            }
        } else if (gradeLevel == GradeLevel::Three) {
            // 大三
            for (Student& s : this->students) {
                double cj_sum = 0.0;  // 总成绩
                double xf_sum = 0.0;  // 总学分
                double gyf = s.getCharityScore();  // 公益分
                double cxf = s.getConductScore();  // 操行分

                // 计算课程成绩、体育成绩
                emit appendInfoMessage("\n开始计算["+s.getName()+"]的成绩：");
                for (Course c : this->courseList) {
                    QRegularExpression re("^体育");
                    if (re.match(c.getName()).hasMatch()) {
                        // 体育成绩
                        s.setTy(s.getCourseScore(c.getId()) * 0.1);

                    } else if (s.getCourseScore(c.getId()) != -1) {
                        // 非体育成绩
                        cj_sum += s.getCourseScore(c.getId()) * c.getXF();
                        xf_sum += c.getXF();
                        emit appendInfoMessage("【"+c.getName()+":"+QString::number(s.getCourseScore(c.getId()))+"/"+QString::number(c.getXF())+"/"+QString::number(cj_sum)+"/"+QString::number(xf_sum)+"】");
                    } else {
                        // 没有选修的课程
                        emit appendInfoMessage("【"+c.getName()+":未修/"+QString::number(c.getXF())+"/"+QString::number(cj_sum)+"/"+QString::number(xf_sum)+"】");
                    }
                }
                // 计算课程成绩
                s.setKc(cj_sum/xf_sum);

                // 计算公益分成绩
                s.setGyf(calculateCharityGrade(gyf));

                // 计算操行分成绩
                s.setCxf(cxf*0.11);

                // 计算奖学金成绩【课程成绩*0.8+操行分*0.11+公益分成绩】
                s.setJxj(s.getKc()*0.8+s.getCxf()+s.getGyf());

                emit appendInfoMessage("\n【课程成绩:"+QString::number(s.getKc())+"】"+
                                       "【体育成绩:大三不计算】"+
                                       "【公益分成绩:"+QString::number(s.getGyf())+"】"+
                                       "【操行分成绩:"+QString::number(s.getCxf())+"】"+
                                       "【奖学金成绩:"+QString::number(s.getJxj())+"】\n");
            }
        } else if (gradeLevel == GradeLevel::Four) {
            // 大四
            for (Student& s : this->students) {
                double cj_sum = 0.0;  // 总成绩
                double xf_sum = 0.0;  // 总学分
                double gyf = s.getCharityScore();  // 公益分
                double cxf = s.getConductScore();  // 操行分

                // 计算课程成绩、体育成绩
                emit appendInfoMessage("\n开始计算["+s.getName()+"]的成绩：");
                for (Course c : this->courseList) {
                    QRegularExpression re("^体育");
                    if (re.match(c.getName()).hasMatch()) {
                        // 体育成绩
                        s.setTy(s.getCourseScore(c.getId()) * 0.1);

                    } else if (s.getCourseScore(c.getId()) != -1) {
                        // 非体育成绩
                        cj_sum += s.getCourseScore(c.getId()) * c.getXF();
                        xf_sum += c.getXF();
                        emit appendInfoMessage("【"+c.getName()+":"+QString::number(s.getCourseScore(c.getId()))+"/"+QString::number(c.getXF())+"/"+QString::number(cj_sum)+"/"+QString::number(xf_sum)+"】");
                    } else {
                        // 没有选修的课程
                        emit appendInfoMessage("【"+c.getName()+":未修/"+QString::number(c.getXF())+"/"+QString::number(cj_sum)+"/"+QString::number(xf_sum)+"】");
                    }
                }
                // 计算课程成绩
                s.setKc(cj_sum/xf_sum);

                // 计算公益分成绩
                s.setGyf(calculateCharityGrade(gyf));

                // 计算操行分成绩
                s.setCxf(cxf*0.11);

                // 计算奖学金成绩【课程成绩*0.89+操行分*0.11】
                s.setJxj(s.getKc()*0.89+s.getCxf());

                emit appendInfoMessage("\n【课程成绩:"+QString::number(s.getKc())+"】"+
                                       "【体育成绩:大四不计算】"+
                                       "【公益分成绩:大四不计算】"+
                                       "【操行分成绩:"+QString::number(s.getCxf())+"】"+
                                       "【奖学金成绩:"+QString::number(s.getJxj())+"】\n");
            }
        }

    } catch (...) {
        emit appendErrorMessage("计算所有学生的奖学金成绩时出现未知错误\n");
        return false;
    }

    emit appendInfoMessage("\n\n已成功计算所有学生的奖学金成绩......(可能有部分学生失败，请查看错误信息)\n");
    return true;
}

double Widget::calculateCharityGrade(int charityGrade)
{
    if (charityGrade >= 300) {
        if (charityGrade <= 1000) {
            return (60 + (charityGrade - 300) * 40.0 / 700) * 0.09;
        } else {
            return (60 + (1000 - 300) * 40.0 / 700) * 0.09;
        }
    } else {
        return charityGrade * 0.2 * 0.09;
    }
}

void Widget::setClassId(const QString &arg1, const QString &arg2, int arg3)
{
    QRegularExpression re1("^\\d{2}$");
    QRegularExpression re2("^\\d{4}$");

    QDate currentDate = QDate::currentDate();
    int currentYear = currentDate.year();
    int difference = 0;

    // 2位数数字
    if (re1.match(arg1).hasMatch()) {
        difference = currentYear - 2000 - arg1.toInt() - 1;
    } else if (re2.match(arg1).hasMatch()) {
        difference = currentYear - arg1.toInt() - 1;
    }

    if (difference <= 3 && difference >= 0) {
        ui->grade->setCurrentIndex(difference);
        if (!arg2.isEmpty()) {
            QString id = QString::number(QDate::currentDate().year() - difference - 2001)+"06";
            if (arg3 == 0) {
                id += "01";
            } else if (arg3 == 1) {
                id += "03";
            } else if (arg3 == 2) {
                id += "05";
            }
            id += QString::number(arg2.toInt(), 16);
            ui->class_id->setText(id);
        }
    }
}

bool Widget::save(QString title, QString table, GradeLevel gradeLevel)
{
    emit appendInfoMessage("\n开始导出所有学生的成绩......\n");
    MyTable myTable(table + "奖学金评定总表", title, this->courseList, this->students, gradeLevel);
    return myTable.saveTable();
}

void Widget::on_start_year_textChanged(const QString &arg1)
{
    QRegularExpression re("^\\d{4}$");
    if (re.match(arg1).hasMatch()) {
        int year = arg1.toInt(); // 将字符串转换为整数
        QString endYear = QString::number(year + 1); // 年份加1并转换回字符串
        ui->end_year->setText(endYear); // 设置 end_year 的文本
    }
}

void Widget::on_end_year_textChanged(const QString &arg1)
{
    QRegularExpression re("^\\d{4}$");
    if (re.match(arg1).hasMatch()) {
        int year = arg1.toInt(); // 将字符串转换为整数
        QString startYear = QString::number(year - 1); // 年份减1并转换回字符串
        ui->start_year->setText(startYear); // 设置 start_year 的文本
    }
}

void Widget::on_grade_num_textChanged(const QString &arg1)
{
    setClassId(arg1, ui->class_num->text(), ui->class_info->currentIndex());
}

void Widget::on_class_num_textChanged(const QString &arg1)
{
    setClassId(ui->grade_num->text(), arg1, ui->class_info->currentIndex());
}

void Widget::on_class_info_activated(int index)
{
    setClassId(ui->grade_num->text(), ui->class_num->text(), index);
}

void Widget::on_btn_course_score_clicked()
{
    courseScorePath = QFileDialog::getOpenFileName(
        this,
        tr("请选择成绩单"), "C:/Users/Feng/Desktop/测试",
        tr("表格 (*.xls *.xlsx);;所有文件 (*.*)"));

    if (!courseScorePath.isEmpty()) {
        QFileInfo fileInfo(courseScorePath);
        ui->course_score->setText(fileInfo.fileName());

        emit appendInfoMessage("导入成绩单："+courseScorePath+"\n");
    }
}

void Widget::on_btn_charity_score_clicked()
{
    charityScorePath = QFileDialog::getOpenFileName(
        this,
        tr("请选择公益分"), "C:/Users/Feng/Desktop/测试",
        tr("表格 (*.xls *.xlsx);;所有文件 (*.*)"));

    if (!charityScorePath.isEmpty()) {
        QFileInfo fileInfo(charityScorePath);
        ui->charity_score->setText(fileInfo.fileName());

        emit appendInfoMessage("导入公益分："+charityScorePath+"\n");
    }
}

void Widget::on_btn_conduct_score_clicked()
{
    conductScorePath = QFileDialog::getOpenFileName(
        this,
        tr("请选择操行分"), "C:/Users/Feng/Desktop/测试",
        tr("表格 (*.xls *.xlsx);;所有文件 (*.*)"));

    if (!conductScorePath.isEmpty()) {
        QFileInfo fileInfo(conductScorePath);
        ui->conduct_score->setText(fileInfo.fileName());

        emit appendInfoMessage("导入操行分："+conductScorePath+"\n");
    }
}

void Widget::on_btn_start_clicked()
{
    QString msg = ui->start_year->text() + "~"
                  + ui->end_year->text() + "学年第"
                  + ui->comboBox->currentText() + "学期"
                  + ui->grade_num->text() + "级"
                  + ui->class_info->currentText()
                  + ui->class_num->text() + "班班级成绩汇总表";
    QString class_id = ui->class_id->text();

    int grade = ui->grade->currentIndex();
    GradeLevel gradeLevel = GradeLevel::None;
    if (grade == 0)  gradeLevel = GradeLevel::One;
    else if (grade == 1) gradeLevel = GradeLevel::Two;
    else if (grade == 2) gradeLevel = GradeLevel::Three;
    else if (grade == 3) gradeLevel = GradeLevel::Four;

    emit appendInfoMessage("开始计算："+msg+"\n");

    // 清空数据
    this->courseList.clear();
    this->students.clear();


    // 加载课程分数
    if (!loadCourse()) {
        emit appendInfoMessage("**********课程加载失败！**********\n");
        return;
    }

    // 加载公益分
    if (!loadCharity()) {
        emit appendInfoMessage("**********公益分加载失败！**********\n");
        return;
    }

    // 加载操行分
    if (!loadConduct()) {
        emit appendInfoMessage("**********操行分加载失败！**********\n");
        return;
    }

    // 计算
    if (!calculate(gradeLevel)) {
        emit appendInfoMessage("**********奖学金成绩计算失败！**********\n");
        return;
    }

    // 选择导出路径
    if (!save(msg, class_id, gradeLevel)) {
        emit appendInfoMessage("**********导出奖学金成绩失败！**********\n");
        return;
    }

    emit appendInfoMessage("**********导出奖学金成绩成功！**********\n保存路径："+QDir::currentPath()+"\n");
}

void Widget::on_btn_show_info_clicked()
{
    ui->stackedWidget->setCurrentIndex(0);
}

void Widget::on_btn_show_error_clicked()
{
    ui->stackedWidget->setCurrentIndex(1);
}

void Widget::on_btn_clear_info_clicked()
{
    emit clearInfoMessage();
}

void Widget::on_btn_clear_error_clicked()
{
    emit clearErrorMessage();
}

void Widget::dealSelectedCourseList(const QList<Course> courseList)
{
    this->courseList = courseList;
}

